home *** CD-ROM | disk | FTP | other *** search
- /*********************************************************************
- File : macperl.mus - Mac specific extensions
- Author : Tim Endres & Matthias Neeracher
- Started : 28May91 Language : MPW C
- Last : 27Dec91
-
- Copyright (c) 1991, 1992 Tim Endres & Matthias Neeracher
- *********************************************************************/
-
- #include <Types.h>
- #include <QuickDraw.h>
- #include <Fonts.h>
- #include <Menus.h>
- #include <TextEdit.h>
- #include <Dialogs.h>
- #include <SegLoad.h>
- #include <StandardFile.h>
- #include <Lists.h>
- #include <Files.h>
-
- /* Ugly hack since QuickDraw defines another invert */
- #define RESOLVE_MAC_CONFLICTS
-
- #include "EXTERN.h"
- #include "perl.h"
-
- extern int wantarray;
-
- char *savestr();
-
- static enum macvars {
- UV_macerr,
- };
-
- static enum macsubs {
- US_mac_sfgetfile,
- US_mac_sfgetfolder,
- US_mac_sfputfile,
- US_mac_answer,
- US_mac_ask,
- US_mac_pick,
- };
-
- static int macsub();
- static int macset();
- static int macval();
-
- static int _mac_error_ = 0;
-
- void InitToolbox()
- {
- InitGraf((Ptr) &qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
- }
-
- int
- init_macintosh()
- {
- struct ufuncs uf;
- char *filename = "macperl.c";
-
- uf.uf_set = macset;
- uf.uf_val = macval;
-
- #define MAGICVAR(name, ix) uf.uf_index = ix, magicname(name, &uf, sizeof uf)
-
- MAGICVAR("macerr", UV_macerr);
-
- make_usub("sfgetfile", US_mac_sfgetfile, macsub, filename);
- make_usub("sfgetfolder",US_mac_sfgetfolder, macsub, filename);
- make_usub("sfputfile", US_mac_sfputfile, macsub, filename);
- make_usub("answer", US_mac_answer, macsub, filename);
- make_usub("ask", US_mac_ask, macsub, filename);
- make_usub("pick", US_mac_pick, macsub, filename);
-
- return 1;
- };
-
- static void CenterWindow(DialogPtr dlg)
- {
- Rect * screen;
- short hPos;
- short vPos;
-
- screen = &qd.screenBits.bounds;
- hPos = screen->right+screen->left-dlg->portRect.right >> 1;
- vPos = (screen->bottom-screen->top-dlg->portRect.bottom)/3;
- vPos += screen->top;
- MoveWindow(dlg, hPos, vPos, true);
- }
-
- static ControlHandle GetDlgCtrl(DialogPtr dlg, short item)
- {
- short kind;
- Handle hdl;
- Rect box;
-
- GetDItem(dlg, item, &kind, &hdl, &box);
- return (ControlHandle) hdl;
- }
-
- static void GetDlgText(DialogPtr dlg, short item, char * text)
- {
- getitext((Handle) GetDlgCtrl(dlg, item), text);
- }
-
- static void SetDlgText(DialogPtr dlg, short item, char * text)
- {
- setitext((Handle) GetDlgCtrl(dlg, item), text);
- }
-
- static void GetDlgRect(DialogPtr dlg, short item, Rect * r)
- {
- short kind;
- Handle hdl;
-
- GetDItem(dlg, item, &kind, &hdl, r);
- }
-
- static void FrameDlgRect(DialogPtr dlg, short item)
- {
- Rect r;
-
- GetDlgRect(dlg, item, &r);
- InsetRect(&r, -4, -4);
- PenSize(3, 3);
- FrameRoundRect(&r, 16, 16);
- PenSize(1,1);
- }
-
- static int
- macsub(ix, sp, items)
- int ix;
- int sp;
- int items;
- {
- STR **st = stack->ary_array + sp;
- STR *Str; /* used in str_get and str_gnum macros */
-
- switch (ix) {
- case US_mac_sfgetfile:
- if (items < 4 || items > 5)
- fatal("Usage: &sfgetfile($h, $v, $filetypes, $filename [, $defaultpath])");
- else {
- int retval;
- int h = (int) str_gnum(st[1]);
- int v = (int) str_gnum(st[2]);
- char* filetypes = (char*) str_get(st[3]);
- char* filename;
- char* defaultpath;
-
- if (items < 5)
- defaultpath = "";
- else
- defaultpath = (char*) str_get(st[5]);
-
- retval = mac_sfgetfile(h, v, defaultpath, filetypes, &filename);
- str_numset(st[0], (double) retval);
- str_set(st[4], (char*) filename);
- }
- return sp;
-
- case US_mac_sfgetfolder:
- if (items < 3 || items > 4)
- fatal("Usage: &sfgetfolder($h, $v, $foldername [, $defaultpath])");
- else {
- int retval;
- int h = (int) str_gnum(st[1]);
- int v = (int) str_gnum(st[2]);
- char* filename;
- char* defaultpath;
-
- if (items < 4)
- defaultpath = "";
- else
- defaultpath = (char*) str_get(st[4]);
-
- retval = mac_sfgetfolder(h, v, defaultpath, &filename);
- str_numset(st[0], (double) retval);
- str_set(st[3], (char*) filename);
- }
- return sp;
-
- case US_mac_sfputfile:
- if (items < 4 || items > 6)
- fatal("Usage: &sfputfile($h, $v, $prompt, $filename [, $defaultname] [, $defaultpath])");
- else {
- int retval;
- int h = (int) str_gnum(st[1]);
- int v = (int) str_gnum(st[2]);
- char* prompt = (char*) str_get(st[3]);
- char* filename;
- char* defaultname;
- char* defaultpath;
-
- if (items < 6)
- defaultpath = "";
- else
- defaultpath = (char*) str_get(st[6]);
-
- if (items < 5)
- defaultname = "Untitled";
- else
- defaultname = (char*) str_get(st[5]);
-
- retval = mac_sfputfile(h, v, prompt, defaultpath, defaultname, &filename);
- str_numset(st[0], (double) retval);
- str_set(st[4], (char*) filename);
- }
- return sp;
-
- case US_mac_ask:
- if (items < 2 || items > 3)
- fatal("Usage: &ask($prompt, $string [, $defaultstr])");
- else {
- int retval;
- char* prompt = (char*) str_get(st[1]);
- char* string;
- char* defaultstr;
-
- if (items < 3)
- defaultstr = "";
- else
- defaultstr = (char*) str_get(st[3]);
-
- retval = mac_ask(prompt, defaultstr, &string);
- str_numset(st[0], (double) retval);
- str_set(st[2], (char*) string);
- }
- return sp;
-
- case US_mac_answer:
- if (items < 1 ||╩items > 4)
- fatal("Usage: &answer($prompt [, $button1] [, $button2] [, $button3] )");
- else {
- int retval;
- int i;
- char* prompt = (char*) str_get(st[1]);
- char* buttons[3];
-
- for (i=1; i++<items;)
- buttons[i-2] = str_get(st[i]);
-
- if (items == 1) {
- buttons[0] = "OK";
- items = 2;
- }
-
- retval = mac_answer(prompt, items-1, buttons);
- str_numset(st[0], (double) retval);
- }
- return sp;
-
- case US_mac_pick:
- if (items < 3)
- fatal("Usage: &pick($prompt, $choice╔, $pick)");
- else {
- int retval;
- char* prompt = (char*) str_get(st[1]);
- char* pick;
-
- retval = mac_list_pick(prompt, st+2, items-2, &pick);
- str_numset(st[0], (double) retval);
- str_set(st[items], (char*) pick);
- }
- return sp;
-
- default:
- fatal("Unimplemented user-defined subroutine");
- break;
- }
-
- return sp;
- }
-
- static int
- macval(ix, str)
- int ix;
- STR *str;
- {
- switch (ix) {
- case UV_macerr:
- str_numset(str, (double)_mac_error_);
- break;
- }
- return 0;
- }
-
- static int
- macset(ix, str)
- int ix;
- STR *str;
- {
- switch (ix) {
- case UV_macerr:
- _mac_error_ = (int)str_gnum(str);
- break;
- }
- return 0;
- }
-
- #define TempPStr(cstr) ((StringPtr) memcpy(tmpPStr+1, cstr, *tmpPStr = strlen(cstr)), tmpPStr)
-
- int
- mac_answer(prompt, butCnt, buttons)
- char * prompt;
- int butCnt;
- char ** buttons;
- {
- short item;
- DialogPtr mydialog;
- Str255 tmpPStr;
-
- mydialog = GetNewDialog(2000+butCnt, NULL, (WindowPtr)-1);
- if (mydialog == NULL)
- return 0;
-
- InitCursor();
- SetDlgText(mydialog, 5, prompt);
-
- for (item = 0; item<butCnt; item++)
- SetCTitle(GetDlgCtrl(mydialog, item+1), TempPStr(buttons[item]));
-
- CenterWindow(mydialog);
- ShowWindow(mydialog);
- SetPort(mydialog);
- FrameDlgRect(mydialog, ok);
- ModalDialog((ModalFilterProcPtr)0, &item);
- DisposDialog(mydialog);
-
- return butCnt-item;
- }
-
- static char string_reply[256];
-
- int
- mac_ask(prompt, defaultstr, string)
- char * prompt;
- char * defaultstr;
- char ** string;
- {
- short item;
- DialogPtr mydialog;
-
- mydialog = GetNewDialog((short)2010, NULL, (WindowPtr)-1);
- if (mydialog == NULL)
- return 0;
-
- SetDlgText(mydialog, 3, prompt);
- if (*defaultstr)
- SetDlgText(mydialog, 4, defaultstr);
- SelIText(mydialog, 4, 0, 1024);
-
- InitCursor();
- CenterWindow(mydialog);
- ShowWindow(mydialog);
- SetPort(mydialog);
- FrameDlgRect(mydialog, ok);
- ModalDialog((ModalFilterProcPtr)0, &item);
- switch (item) {
- case ok:
- GetDlgText(mydialog, 4, string_reply);
- *string = string_reply;
- break;
- case cancel:
- break;
- }
- DisposDialog(mydialog);
-
- return 2-item;
- }
-
- #define SFSaveDisk (* (short *) 0x0214)
- #define CurDirStore (* (long *) 0x0398)
-
- int
- mac_sfgetfile(h, v, defaultpath, filetypes, filepath)
- int h, v;
- char *defaultpath;
- char *filetypes;
- char **filepath;
- {
- int i, length, num_types = -1;
- long savedir;
- short savedisk;
- char *ptr;
- Point mypoint;
- SFTypeList mytypes;
- SFReply myreply;
- FSSpec desc;
-
- mypoint.h = h;
- mypoint.v = v;
- length = strlen(filetypes);
- for (i=0,ptr=filetypes ; length >= 4 && i < 4 ; length -= 4, i++, ptr+=4) {
- strncpy((char *)&mytypes[i], ptr, 4);
- num_types += (num_types == -1) ? 2 : 1;
- }
-
- if (*defaultpath) {
- savedisk = SFSaveDisk;
- savedir = CurDirStore;
- if (!Path2FSSpec(defaultpath, &desc) && !FSpDown(&desc, "")) {
- SFSaveDisk = -desc.vRefNum;
- CurDirStore = desc.parID;
- }
- }
-
- SFGetFile(mypoint, "\p", NULL, num_types, mytypes, NULL, &myreply);
- if (myreply.good) {
- WD2FSSpec(myreply.vRefNum, myreply.fName, &desc);
- *filepath = FSp2FullPath(&desc);
- }
-
- if (*defaultpath) {
- SFSaveDisk = savedisk;
- CurDirStore = savedir;
- }
-
- return myreply.good;
- }
-
- static long currentDir;
- static SFReply reply;
-
- static pascal Boolean FolderFFilter(ParmBlkPtr p)
- {
- return !(p->fileParam.ioFlAttrib & ioDirMask);
- }
-
- static pascal short GetDirDlgHook(short item, DialogPtr dlgPtr)
- {
- switch (item) {
- case 11:
- if (reply.fType) {
- currentDir = reply.fType;
- return 1;
- }
- break;
-
- case 12:
- currentDir = CurDirStore;
-
- return 1;
- case 100:
- if (!reply.fType)
- HiliteControl(GetDlgCtrl(dlgPtr, 11), 255);
- else
- HiliteControl(GetDlgCtrl(dlgPtr, 11), 0);
- break;
- }
-
- return item;
- }
-
- int
- mac_sfgetfolder(h, v, defaultpath, filepath)
- int h, v;
- char *defaultpath;
- char **filepath;
- {
- long savedir;
- short savedisk;
- Point mypoint;
- FSSpec desc;
-
- mypoint.h = h;
- mypoint.v = v;
-
- if (*defaultpath) {
- savedisk = SFSaveDisk;
- savedir = CurDirStore;
- if (!Path2FSSpec(defaultpath, &desc) && !FSpDown(&desc, "")) {
- SFSaveDisk = -desc.vRefNum;
- CurDirStore = desc.parID;
- }
- }
-
- SFPGetFile(
- mypoint,
- '',
- FolderFFilter,
- -1,
- nil,
- GetDirDlgHook,
- &reply,
- 2030,
- nil);
-
- if (reply.good) {
- desc.vRefNum = -SFSaveDisk;
- desc.parID = currentDir;
- if (FSpUp(&desc))
- return false;
- *filepath = FSp2FullPath(&desc);
- }
-
- if (*defaultpath) {
- SFSaveDisk = savedisk;
- CurDirStore = savedir;
- }
-
- return reply.good;
- }
-
- int
- mac_sfputfile(h, v, prompt, defaultpath, defaultname, filepath)
- int h, v;
- char *prompt;
- char *defaultpath;
- char *defaultname;
- char **filepath;
- {
- long savedir;
- short savedisk;
- Point mypoint;
- SFReply myreply;
- FSSpec desc;
-
- mypoint.h = h;
- mypoint.v = v;
-
- if (*defaultpath) {
- savedisk = SFSaveDisk;
- savedir = CurDirStore;
- if (!Path2FSSpec(defaultpath, &desc) && !FSpDown(&desc, "")) {
- SFSaveDisk = -desc.vRefNum;
- CurDirStore = desc.parID;
- }
- }
-
- sfputfile(&mypoint, prompt, defaultname, NULL, &myreply);
- if (myreply.good) {
- WD2FSSpec(myreply.vRefNum, myreply.fName, &desc);
- *filepath = FSp2FullPath(&desc);
- }
-
- if (*defaultpath) {
- SFSaveDisk = savedisk;
- CurDirStore = savedir;
- }
-
- return myreply.good;
- }
-
- static ListHandle picklist = NULL;
-
- #define SetCell(cell, row, column) { (cell).h = column; (cell).v = row; }
- #define ROW(cell) (cell).v
-
- pascal void
- MacListUpdate(myDialog, myItem)
- DialogPtr myDialog;
- short myItem;
- {
- Rect myrect;
- #pragma unused (myItem)
-
- LUpdate(myDialog->visRgn, picklist);
- myrect = (**(picklist)).rView;
- InsetRect(&myrect, -1, -1);
- FrameRect(&myrect);
- }
-
- pascal Boolean
- MacListFilter(myDialog, myEvent, myItem)
- DialogPtr myDialog;
- EventRecord *myEvent;
- short *myItem;
- {
- Rect listrect;
- short myascii;
- Handle myhandle;
- Point mypoint;
- short mytype;
- int activate;
-
- SetPort(myDialog);
- if (myEvent->what == keyDown) {
- myascii = myEvent->message % 256;
- if (myascii == '\015' || myascii == '\003') { /* This is return or enter... */
- *myItem = 1;
- return true;
- }
- }
- else if (myEvent->what == mouseDown) {
- mypoint = myEvent->where;
- GlobalToLocal(&mypoint);
- GetDItem(myDialog, 4, &mytype, &myhandle, &listrect);
- if (PtInRect(mypoint, &listrect) && picklist != NULL) {
- if (LClick(mypoint, (short)myEvent->modifiers, picklist)) {
- /* User double-clicked in cell... */
- *myItem = 1;
- return true;
- }
- }
- }
- else if (myEvent->what == activateEvt && picklist != NULL) {
- activate = (myEvent->modifiers & 0x01) != 0;
- LActivate((Boolean) activate, picklist);
- }
-
- return false;
- }
-
- mac_list_pick(prompt, list_string, count, pick)
- char *prompt;
- STR ** list_string;
- int count;
- char **pick;
- {
- short itemHit, length;
- Boolean done;
- DialogPtr mydialog;
- ListHandle mylist;
- Cell mycell;
- short mytype;
- Handle myhandle;
- Point cellsize;
- Rect listrect, dbounds;
- char * item;
-
- InitCursor();
- mydialog = GetNewDialog(2020, NULL, (WindowPtr)-1);
- if (!mydialog)
- return 0;
-
- SetDlgText(mydialog, 3, prompt);
- GetDItem(mydialog, 4, &mytype, &myhandle, &listrect);
- SetDItem(mydialog, 4, mytype, (Handle)MacListUpdate, &listrect);
-
- SetPort(mydialog);
- InsetRect(&listrect, 1, 1);
- SetRect(&dbounds, 0, 0, 1, count);
- cellsize.h = (listrect.right - listrect.left);
- cellsize.v = 17;
-
- listrect.right -= 15;
-
- picklist = LNew(&listrect, &dbounds, cellsize, 0,
- mydialog, true, false, false, true);
-
- mylist = picklist;
- LDoDraw(false, mylist);
-
- SetCell(mycell, 0, 0);
- for (; mycell.v <count; ++mycell.v) {
- item = str_get(list_string[mycell.v]);
- LSetCell(item, strlen(item), mycell, mylist);
- }
-
- LDoDraw(true, mylist);
- CenterWindow(mydialog);
- ShowWindow(mydialog);
-
- for (done=false; !done; ) {
- SetPort(mydialog);
- FrameDlgRect(mydialog, ok);
- ModalDialog(MacListFilter, &itemHit);
- switch (itemHit) {
- case ok:
- SetCell(mycell, 0, 0);
- done = true;
- if (LGetSelect(true, &mycell, picklist)) {
- length = 255;
- LGetCell(string_reply, &length, mycell, picklist);
- string_reply[length] = '\0';
- *pick = string_reply;
- break;
- } else
- itemHit = cancel;
- break;
- case cancel:
- done = true;
- break;
- }
-
- } /* Modal Loop */
-
- SetPort(mydialog);
-
- LDispose(mylist);
- picklist = NULL;
- DisposDialog(mydialog);
-
- return (itemHit == ok);
- }
-
- void SpinPerlCursor(int direction)
- {
- static int delay = 0;
-
- if (!(delay++ % 10))
- SpinCursor(direction);
- }
-
- void GetProgFile(FSSpec * desc)
- {
- short message;
- short count;
-
- CountAppFiles(&message, &count);
-
- if (count) {
- AppFile arg;
-
- GetAppFiles(1, &arg);
-
- if (arg.fType != 'TEXT')
- fatal("MacPerl can't do anything with a non-text file.\n");
-
- WD2FSSpec(arg.vRefNum, arg.fName, desc);
- } else {
- Point wh;
- SFTypeList types;
- SFReply reply;
-
- wh.h = wh.v = 75;
- types[0] = 'TEXT';
-
- SFGetFile(wh, "", (FileFilterProcPtr) nil, 1, types, (DlgHookProcPtr) nil, &reply);
-
- if (!reply.good)
- fatal("MacPerl needs a program file to run.\n");
-
- WD2FSSpec(reply.vRefNum, reply.fName, desc);
- }
- }
-